package com.authsphere.plugin.base.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.util.ReflectionUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @program: AuthSphere
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/27 21:03
 **/
public class AnnotationProcessor {

    /**
     * 获取被注解属性
     * @param obj
     * @param annotationClass
     * @return
     */
    public static Field getAnnotatedField(Object obj, Class<? extends Annotation> annotationClass) {
        Field annotatedField = null;
        for (Field field : obj.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(annotationClass)) {
                annotatedField = field;
                annotatedField.setAccessible(true);
                break;
            }
        }
        return annotatedField;
    }

    /**
     * 获取被注解属性的getter方法
     * @param obj real object
     * @param annotationClass real annotation
     * @return the getter method
     */
    public static Method getAnnotatedGetterMethod(Object obj, Class<? extends Annotation> annotationClass) {
        Field annotatedField = null;
        for (Field field : obj.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(annotationClass)) {
                annotatedField = field;
                break;
            }
        }
        if (annotatedField != null) {
            String getterMethodName = "get" + capitalize(annotatedField.getName());
            return ReflectionUtils.findMethod(obj.getClass(), getterMethodName);
        }
        return null;
    }

    /**
     * 获取被注解属性的getter方法
     * @param obj real object
     * @param annotationClass real annotation
     * @return the getter method
     */
    public static Pair<Field, Method[]> getAnnotatedGetterAndSetterMethod(Object obj, Class<? extends Annotation> annotationClass) {
        Field annotatedField = null;
        for (Field field : obj.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(annotationClass)) {
                annotatedField = field;
                break;
            }
        }
        if (annotatedField != null) {
            String getterMethodName = "get" + capitalize(annotatedField.getName());
            String setterMethodName = "set" + capitalize(annotatedField.getName());
            Method getterMethod = ReflectionUtils.findMethod(obj.getClass(), getterMethodName);
            Method setterMethod = ReflectionUtils.findMethod(obj.getClass(), setterMethodName, String.class);
            return ImmutablePair.of(annotatedField, new Method[]{getterMethod, setterMethod});
        }
        return null;
    }

    private static String capitalize(String name) {
        if (StringUtils.isBlank(name)) {
            return name;
        }
        return name.substring(0, 1).toUpperCase() + name.substring(1);
    }
}
